package com.hexacta.hrs.domain.staffing.relationship.generators;

import java.util.Calendar;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.Predicate;

import com.hexacta.hrs.domain.staffing.Requirement;
import com.hexacta.hrs.domain.staffing.assignment.EmployeeAssignment;
import com.hexacta.hrs.domain.staffing.relationship.RequirementAssignmentRelationship;

/**
 * Genera las relaciones entre las asignaciones a los proyectos y sus requerimientos.
 *
 * @author ncortinez
 *
 */
public class AssignmentRelationshipGenerator {

	public AssignmentRelationshipGenerator(){
	}

	/**
	 * 	Devuelve todos los Assigned Requirements resultante de la relacion entre los requerimientos y las asignaciones pasadas por parametro.
	 * 		Assigned Requirement: es el caso en el que una asignacion esta cubriendo un requerimiento de un proyecto.
	 */
	public List<RequirementAssignmentRelationship> getAssignedRequirements(Set<Requirement> requirements, List<EmployeeAssignment>  assignments){
		return RequirementAssignmentGenerator.generate(requirements, assignments);
	}

	/**
	 * 	Devuelve todos los Non Requirement Assignments resultante de la relacion entre los requerimientos y las asignaciones pasadas por parametro.
	 * 		Non Requirement Assignment: es el caso en el que un recurso esta asignado a un proyecto, pero no existe un requerimiento que lo concuerde.
	 */
	public List<RequirementAssignmentRelationship> getNonRequirementAssignments(Set<Requirement> requirements, List<EmployeeAssignment> assignments){
		return NonRequirementAssignmentGenerator.generate(requirements, assignments);
	}

	/**
	 * 	Devuelve todos los Unassigned Requirements resultante de la relacion entre los requerimientos y las asignaciones pasadas por parametro.
	 * 		Unassigned Requirement: es el caso en que un requerimiento no es cubierto por una asignacion.
	 */
	public List<RequirementAssignmentRelationship> getUnassignedRequirements(Set<Requirement> requirements, List<EmployeeAssignment> assignments){
		return UnassignedRequirementGenerator.generate(requirements, assignments);
	}
}

class CumpleRangoDeFechasConPorcentajeMayor implements Predicate {

	private Calendar startDate;
	private Calendar endDate;
	private double porcentaje;
	private String rol;

	public CumpleRangoDeFechasConPorcentajeMayor(EmployeeAssignment assignment) {
		this.startDate = assignment.getStartDate();
		this.endDate = assignment.getEndDate();
		this.porcentaje = assignment.getAssignmentPorcentage();
		this.rol = assignment.getAssignedRole().getDescription();
	}

	@Override
	public boolean evaluate(Object arg) {
		Requirement req = (Requirement)arg;
		return (req.getRequiredRol().getDescription().equals(rol)
					&& (req.getStartDate().compareTo(startDate) <= 0)
						&&((req.getEndDate().compareTo(endDate) >= 0))
							&&(req.getAssignmentPorcentage() >= porcentaje));
	}
}

class CumpleRangoDeFechasConPorcentajeMenor implements Predicate {
	private Calendar startDate;
	private Calendar endDate;
	private double porcentaje;
	private String rol;

	public CumpleRangoDeFechasConPorcentajeMenor(EmployeeAssignment assignment) {
		this.startDate = assignment.getStartDate();
		this.endDate = assignment.getEndDate();
		this.porcentaje = assignment.getAssignmentPorcentage();
		this.rol = assignment.getAssignedRole().getDescription();
	}

	@Override
	public boolean evaluate(Object arg) {
		Requirement req = (Requirement)arg;
		return (req.getRequiredRol().getDescription().equals(rol)
					&& (req.getStartDate().compareTo(startDate) <= 0)
						&&((req.getEndDate().compareTo(endDate) >= 0))
							&&(req.getAssignmentPorcentage() < porcentaje));
	}
}

